#pragma once
#include <semaphore.h>
const int defaultNum=10;
#include<iostream>
#include<vector>
template<class T>
class RingQueue
{
    private:
   int index_p;//生产者下标
   int index_c;//消费者下标
   std::vector<T> ringqueue_;//数据的存放位置（交易场所）
    sem_t space_sem_p;//生产者关注空间资源
    sem_t data_sem_c;//消费者关注数据资源
    pthread_mutex_t mutex_;
    private:
    void P( sem_t& sem)
    {
        sem_wait(&sem);//--
    }
    void V( sem_t& sem)
    {
        sem_post(&sem);//++
    }
    void lock()
    {
        pthread_mutex_lock(&mutex_);
    }
    void unlock()
    {
        pthread_mutex_unlock(&mutex_);
    }
    public:
    RingQueue(int capacity=defaultNum)
    :index_c(0),index_p(0),ringqueue_(defaultNum)
    {
        //初始化信号量
        sem_init(&space_sem_p,0,defaultNum);
        sem_init(&data_sem_c,0,0);
        pthread_mutex_init(&mutex_,nullptr);
    }
    void push(const T& data)
    {
        //入数据
        //先申请信号量（申请空间资源的信号量）
        P(space_sem_p);//先确保申请成功再让进来
        lock();//进来要上锁

        ringqueue_[index_p]=data;
        index_p++;
        index_p%=ringqueue_.size();
        unlock();
        V(data_sem_c);
    }
    T pop()
    {
        //出数据
        P(data_sem_c);
        lock();
        T out=ringqueue_[index_c];
        index_c++;
        index_c%=ringqueue_.size();
        unlock();
        V(space_sem_p);
        return out;
    }
    ~RingQueue()
    {
        //信号量销毁
        sem_destroy(&space_sem_p);
        sem_destroy(&data_sem_c);
        pthread_mutex_destroy(&mutex_);
    }
};